www.gusucode.com > VC++ 模仿MSN界面 > VC++ 模仿MSN界面/gusucode/MSN/MsnEdit.cpp

    //Download by http://www.NewXing.com
// EditWithButton.cpp : implementation file

#include "stdafx.h"
#include "MsnEdit.h"

// CMsnEdit

IMPLEMENT_DYNAMIC(CMsnEdit, CEdit)

CMsnEdit::CMsnEdit()
{
	m_iButtonClickedMessageId = WM_USER_EDITBUTTON_CLICKED;
	m_bButtonExistsAlways = FALSE;

	m_rcEditArea.SetRect(0,0,0,0);

}

CMsnEdit::~CMsnEdit()
{

}


BEGIN_MESSAGE_MAP(CMsnEdit, CEdit)
	ON_MESSAGE(WM_SETFONT, OnSetFont)
	ON_WM_SIZE()
	ON_WM_ERASEBKGND()
	ON_WM_CHAR()
	ON_WM_KEYDOWN()
	ON_WM_LBUTTONUP()
	ON_WM_SETCURSOR()
	ON_WM_CREATE()
END_MESSAGE_MAP()



// CMsnEdit message handlers

void CMsnEdit::PreSubclassWindow( )
{	
	// We must have a multiline edit
	// to be able to set the edit rect
	ASSERT( GetStyle() & ES_MULTILINE );

	ResizeWindow();
	CEdit::PreSubclassWindow();
}

BOOL CMsnEdit::PreTranslateMessage( MSG* pMsg )
{
	return CEdit::PreTranslateMessage(pMsg);
}

BOOL CMsnEdit::SetBitmaps(CString EmptyEdit, CString FilledEdit)
{
	//delete if already loaded.. just in case
	m_bmpEmptyEdit = EmptyEdit;
	m_bmpFilledEdit = FilledEdit;
	
	return TRUE;

}

//client area
void CMsnEdit::SetButtonArea(CRect rcButtonArea)
{
	m_rcButtonArea = rcButtonArea;
}

void CMsnEdit::ResizeWindow()
{
	if (!::IsWindow(m_hWnd)) return;

	//proceed only if edit area is set
	if (m_rcEditArea == CRect(0,0,0,0)) return;

//	if (GetWindowTextLength() == 0)
	//	{
	//		SetWindowPos(&wndTop,0,0,m_sizeEmptyBitmap.cx,m_sizeEmptyBitmap.cy,SWP_NOMOVE|SWP_NOZORDER);
	//	}else
	//	{
	//		SetWindowPos(&wndTop,0,0,m_sizeFilledBitmap.cx,m_sizeFilledBitmap.cy,SWP_NOMOVE|SWP_NOZORDER);
	//	}
	

	SetRect(&m_rcEditArea);

}


//set edit area may be called before creating the edit control
//especially when using the CEdit::Create method
//or after creating the edit control in CEdit::DoDataExchange
//we call ResizeWindow once in SetEditArea and once in PreSubclassWindow
BOOL CMsnEdit::SetEditArea(CRect rcEditArea)
{
	m_rcEditArea = rcEditArea;

	ResizeWindow();

	return TRUE;
}

void CMsnEdit::SetButtonClickedMessageId(UINT iButtonClickedMessageId)
{
	m_iButtonClickedMessageId = iButtonClickedMessageId;

}

void CMsnEdit::SetButtonExistsAlways(BOOL bButtonExistsAlways)
{
	m_bButtonExistsAlways = bButtonExistsAlways;
}


BOOL CMsnEdit::OnEraseBkgnd(CDC* pDC)
{

	CRect rc;
	GetClientRect(rc);

	int iTextLength = GetWindowTextLength();
   
	if (iTextLength == 0)
	{
		DrawSkinImageRes(pDC->m_hDC, rc, m_bmpEmptyEdit, 15, 35, 15, 15, FALSE);
	}
	else
	{
		DrawSkinImageRes(pDC->m_hDC, rc, m_bmpFilledEdit, 15, 35, 15, 15, FALSE);		
	}

	return TRUE;
}

void CMsnEdit::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
	//this will draw the background again
	//so that the button will be drawn if the text exists

	InvalidateRect(NULL);

	CEdit::OnKeyDown(nChar, nRepCnt, nFlags);
}

void CMsnEdit::OnLButtonUp(UINT nFlags, CPoint point)
{
	if (m_rcButtonArea.PtInRect(point))
	{
		if ( (GetWindowTextLength() > 0) || m_bButtonExistsAlways)
		{
			CWnd *pOwner = GetOwner();
			if (pOwner)
			{
				pOwner->SendMessage(m_iButtonClickedMessageId,0,0);
			}
		}
	}

	CEdit::OnLButtonUp(nFlags, point);
}

BOOL CMsnEdit::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
	CPoint pntCursor;
	GetCursorPos(&pntCursor);
	ScreenToClient(&pntCursor);
	//show arrow cursor
	if (!m_rcEditArea.PtInRect(pntCursor))
	{
		SetCursor(AfxGetApp()->LoadStandardCursor(MAKEINTRESOURCE(32649)));
		return TRUE;
	}

	return CEdit::OnSetCursor(pWnd, nHitTest, message);
}



int CMsnEdit::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CEdit::OnCreate(lpCreateStruct) == -1)
		return -1;

	ResizeWindow();

	return 0;
}


LRESULT CMsnEdit::OnSetFont( WPARAM wParam, LPARAM lParam )
{
	DefWindowProc( WM_SETFONT, wParam, lParam );

	ResizeWindow();

	return 0;

}

void CMsnEdit::OnSize( UINT nType, int cx, int cy ) 
{
	CEdit::OnSize( nType, cx, cy );
	m_rcEditArea = CRect(20,9,cx-35,22);
	m_rcButtonArea = CRect(cx-30,0,30,32);
	SetRect(CRect(20,9,cx-35,22));
}